package com.punai.customer.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.punai.common.core.domain.TreeBo;
import com.punai.common.exception.ServiceException;
import com.punai.common.utils.SecurityUtils;
import com.punai.common.utils.StringUtils;
import com.punai.customer.domain.CusFbChapter;
import com.punai.customer.domain.CusFbFee;
import com.punai.customer.domain.CusLinkFbFeature;
import com.punai.customer.domain.CusLinkFbGx;
import com.punai.customer.domain.contants.CusConstants;
import com.punai.customer.mapper.CusFbChapterMapper;
import com.punai.customer.mapper.CusFbFeeMapper;
import com.punai.customer.mapper.CusLinkFbFeatureMapper;
import com.punai.customer.mapper.CusLinkFbGxMapper;
import com.punai.customer.service.ICusFbChapterService;
import com.punai.standard.domain.StaFbChapter;
import com.punai.standard.mapper.StaFbChapterMapper;
import com.punai.standard.mapper.StaVersionMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 分包费用项章节Service业务层处理
 *
 * @author ruoyi
 * @date 2022-12-09
 */
@Service
public class CusFbChapterServiceImpl extends ServiceImpl<CusFbChapterMapper, CusFbChapter> implements ICusFbChapterService
{
    @Autowired
    private CusFbChapterMapper dmcFbChapterMapper;

    @Autowired
    private CusFbFeeMapper cusFbFeeMapper;

    @Autowired
    private CusLinkFbGxMapper cusLinkFbGxMapper;
    @Autowired
    private CusLinkFbFeatureMapper cusLinkFbFeatureMapper;
    @Autowired
    private StaVersionMapper staVersionMapper;
    @Autowired
    private StaFbChapterMapper staFbChapterMapper;
    /**
     * 查询分包费用项章节
     *
     * @param id 分包费用项章节主键
     * @return 分包费用项章节
     */
    @Override
    public CusFbChapter selectDmcFbChapterById(String id)
    {
        return dmcFbChapterMapper.selectDmcFbChapterById(id);
    }

    /**
     * 查询分包费用项章节列表
     *
     * @param dmcFbChapter 分包费用项章节
     * @return 分包费用项章节
     */
    @Override
    public List<CusFbChapter> selectDmcFbChapterList(CusFbChapter dmcFbChapter)
    {
        return dmcFbChapterMapper.selectDmcFbChapterList(dmcFbChapter);
    }

    /**
     * 新增分包费用项章节
     *
     * @param dmcFbChapter 分包费用项章节
     * @return 结果
     */
    @Override
    public int insertDmcFbChapter(CusFbChapter dmcFbChapter)
    {
            return dmcFbChapterMapper.insert(dmcFbChapter);
    }

    /**
     * 修改分包费用项章节
     *
     * @param dmcFbChapter 分包费用项章节
     * @return 结果
     */
    @Override
    public int updateDmcFbChapter(CusFbChapter dmcFbChapter)
    {
        return dmcFbChapterMapper.updateById(dmcFbChapter);
    }

    /**
     * 批量删除分包费用项章节
     *
     * @param ids 需要删除的分包费用项章节主键
     * @return 结果
     */
    @Override
    public int deleteDmcFbChapterByIds(String[] ids)
    {
        return dmcFbChapterMapper.deleteDmcFbChapterByIds(ids);
    }



    /**
     * 删除分包费用项章节信息
     *
     * @param id 分包费用项章节主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteDmcFbChapterById(String id,Long companyId,String shape)
    {
        List<String> childrenIds = dmcFbChapterMapper.selectChildrenIdById(id, companyId);
        childrenIds.add(id);
        if (StringUtils.equals(shape, "Y")) {
            List<String> itemIds = cusFbFeeMapper.selectIdsByChapterIds(companyId, childrenIds);
            if(CollUtil.isNotEmpty(itemIds)){
                // 删除关联关系
                cusLinkFbGxMapper.delete(
                        Wrappers.<CusLinkFbGx>lambdaQuery()
                                .eq(CusLinkFbGx::getCompanyId,companyId)
                                .in(CusLinkFbGx::getFbId,itemIds)
                );
                // 删除关联特征
                cusLinkFbFeatureMapper.delete(
                        Wrappers.<CusLinkFbFeature>lambdaQuery()
                                .in(CusLinkFbFeature::getItemId,itemIds)
                                .eq(CusLinkFbFeature::getCompanyId,companyId)
                );
                // 删除费用项
                cusFbFeeMapper.delete(
                        Wrappers.<CusFbFee>lambdaQuery()
                                .in(CusFbFee::getId,itemIds)
                                .eq(CusFbFee::getCompanyId,companyId)
                );
            }
        } else {
            cusFbFeeMapper.updateChapterIdIsZero(childrenIds, companyId, CusConstants.CHAPTER_ID_NULL);
        }
        dmcFbChapterMapper.delete(
                Wrappers.<CusFbChapter>lambdaQuery()
                .in(CusFbChapter::getId,childrenIds)
                .eq(CusFbChapter::getCompanyId,companyId)
        );
        return 200;
    }

    @Override
    public List<TreeBo> treeData(Long companyId) {
        List<CusFbChapter> cusFbChapters = dmcFbChapterMapper.selectList(
                Wrappers.<CusFbChapter>lambdaQuery().eq(CusFbChapter::getCompanyId, companyId)
        );
        return TreeBo.convert(cusFbChapters);
    }

    @Override
    public List<TreeBo> getSpecialtyList(Long companyId) {
        List<CusFbChapter> cusFbChapters = dmcFbChapterMapper.selectList(
                Wrappers.<CusFbChapter>lambdaQuery()
                        .eq(CusFbChapter::getCompanyId, companyId)
                        .eq(CusFbChapter::getPid, CusConstants.DEF_PID)
        );
        return TreeBo.sortConvert(cusFbChapters);
    }

    @Override
    public List<TreeBo> treeDataByTopId(String topId, Long companyId) {
        List<CusFbChapter> dmcFbChapters =  dmcFbChapterMapper.selectListByTopId(topId,companyId);
        List<TreeBo> convert = TreeBo.sortConvert(dmcFbChapters);
        if (CollUtil.isNotEmpty(convert)) {
            for (TreeBo treeBo : convert) {
                List<TreeBo> children = treeBo.getChildren();
                for (TreeBo child : children) {
                    child.setFbId(child.getId());
                    setChildrenFbId(child);
                }
            }
            return convert.get(0).getChildren();
        }
        return convert;
    }

    private void setChildrenFbId(TreeBo child) {
        List<TreeBo> children = child.getChildren();
        String fbId = child.getFbId();
        if (CollUtil.isNotEmpty(children)) {
            for (TreeBo treeBo : children) {
                treeBo.setFbId(fbId);
                setChildrenFbId(treeBo);
            }
        }
    }

    @Override
    public CusFbChapter selectFbChapterById(String id, Long companyId) {
        return getById(id,companyId);
    }

    @Override
    @Transactional
    public int insertFbChapter(CusFbChapter fbChapter, Long companyId) {
        fbChapter.setCompanyId(companyId);
        String pid = fbChapter.getPid();
        if (StrUtil.isEmpty(pid)) {
            pid = CusConstants.DEF_PID;
            fbChapter.setPids(pid);
            fbChapter.setPid(pid);
            fbChapter.setSpecId(fbChapter.getId());
        } else {
            CusFbChapter chapter = getById(pid, fbChapter.getCompanyId());
            String pids = chapter.getPids();
            if (StrUtil.isEmpty(pids)) {
                pids = CusConstants.DEF_PID;
            }
            fbChapter.setSpecId(chapter.getSpecId());
            fbChapter.setPids(pids + "," + chapter.getId());
        }
        Integer maxOrderNum = maxOrderNum(pid,companyId);
        fbChapter.setOrderNum(maxOrderNum + 1);
        fbChapter.setOperation(CusConstants.OPERATION_Y_TYPE);
        return dmcFbChapterMapper.insert(fbChapter);
    }

    @Override
    public int updateFbChapter(CusFbChapter dmcFbChapter, Long companyId) {
        // 修改只能改名称
        CusFbChapter updateEntity = new CusFbChapter();
        updateEntity.setName(dmcFbChapter.getName());
        LambdaQueryWrapper<CusFbChapter> eq = Wrappers.<CusFbChapter>lambdaQuery()
                .eq(CusFbChapter::getCompanyId, SecurityUtils.getCompanyId()).eq(CusFbChapter::getId, dmcFbChapter.getId());
        return dmcFbChapterMapper.update(updateEntity,eq);
    }

    @Override
    @Transactional
    public void moveTree(String type, String id, String dropId, Long companyId) {
        if (!StrUtil.containsAny(type,"inner","before","after")) {
            throw new ServiceException("参数错误!");
        }

        CusFbChapter chapter = getById(dropId, companyId);
        CusFbChapter moveChapter = getById(id, companyId);

        if(!StringUtils.equals(moveChapter.getSpecId(),chapter.getSpecId())){
            throw new ServiceException("出现问题数据,请联系管理员!");
        }
        // 处理 移动数据之后的数据
        String targetPid = chapter.getPid();
        String movePid = moveChapter.getPid();
        boolean isProcessLastOrderNum = false;
        // 切换层级了
        boolean changeParent = false;
        if (!StrUtil.equals(targetPid,movePid)) {
            changeParent = true;
            // 发生了pid替换
            // 将之后的章节的 orderNum - 1
            orderNumProcess(companyId,movePid,moveChapter.getOrderNum(),-1);
            isProcessLastOrderNum = true;
            chapter = getById(dropId, companyId);
            moveChapter = getById(id, companyId);
        }
        if ( StringUtils.equals(type,"inner")) {
            // 处理后面的节点
            if (!isProcessLastOrderNum) {
                orderNumProcess(companyId,movePid,moveChapter.getOrderNum(),-1);
                chapter = getById(dropId, companyId);
                moveChapter = getById(id, companyId);
            }
            // 放到了谁的里面 成为了谁的孩子 会成为最后一个
            // 处理序号
            Integer targetOrderNum = maxOrderNum(chapter.getId(),companyId);
            moveChapter.setOrderNum(targetOrderNum + 1);
            String newPids = StrUtil.emptyToDefault(chapter.getPids(),"0") + "," + chapter.getId();
            String oldPids = moveChapter.getPids();
            moveChapter.setPid(chapter.getId());
            moveChapter.setPids(newPids);
            // 处理子节点的pid
            updateChapterChildrenPids(moveChapter.getId(),companyId,newPids,oldPids);
        } else if( StringUtils.equals(type,"before")) {
            if (changeParent) {
                // 在谁之前
                Integer targetOrderNum = chapter.getOrderNum();
                // 处理目标之后的序号
                orderNumProcess(companyId,targetPid,targetOrderNum,+1);
                // 处理目标序号
                chapter.setOrderNum(targetOrderNum + 1);
                // 把目标序号赋给插入进来的对象
                moveChapter.setOrderNum(targetOrderNum);
            } else {
                // 同层
                Integer targetOrderNum = chapter.getOrderNum();
                Integer orderNum = moveChapter.getOrderNum();
                int num = 1;
                // 目标序号大于 当前序号
                // 下移   中间需要 -1
                // 自身 = 目标序号 - 1

                // 如果目标序号 小于当前序号
                // 上移   中间需要 +1
                // 自身 = 目标序号
                // 目标 = 目标序号 + 1
                if (targetOrderNum > orderNum) {
                    num = -1;
                }
                if (Math.abs(targetOrderNum-orderNum) == 1) {
                    chapter.setOrderNum(orderNum);
                    moveChapter.setOrderNum(targetOrderNum);
                } else {
                    orderNumProcessStartEnd(companyId,targetPid,Math.min(targetOrderNum,orderNum),Math.max(targetOrderNum,orderNum),num);
                    if (num == 1) {
                        // 目标序号 小于 当前当前 上移
                        // 自身 = 目标序号
                        moveChapter.setOrderNum(targetOrderNum);
                        // 目标
                        chapter.setOrderNum(targetOrderNum + 1);
                    } else {
                        // 目标序号 大于 当前当前 下移
                        // 自身 = 目标序号 - 1
                        moveChapter.setOrderNum(targetOrderNum - 1);
                    }
                }
            }
        } else if( StringUtils.equals(type,"after")) {
            if (changeParent) {
                // 在谁之后
                Integer targetOrderNum = chapter.getOrderNum();
                // 处理目标之后的序号
                orderNumProcess(companyId,targetPid,targetOrderNum,+1);
                // 把目标序号赋给插入进来的对象
                moveChapter.setOrderNum(targetOrderNum + 1);
            } else {
                Integer targetOrderNum = chapter.getOrderNum();
                Integer orderNum = moveChapter.getOrderNum();
                // 之后

                // 目标序号大于 当前序号
                // 下移   中间需要 -1
                // 自身 = 目标序号
                // 目标 = 目标序号 - 1

                // 如果目标序号 小于当前序号
                // 上移   中间需要 +1
                // 自身 = 目标序号 + 1
                // 目标 = 目标序号

                int num = 1;
                if (targetOrderNum > orderNum) {
                    num = -1;
                }
                if (Math.abs(targetOrderNum-orderNum) == 1) {
                    chapter.setOrderNum(orderNum);
                    moveChapter.setOrderNum(targetOrderNum);
                } else {
                    orderNumProcessStartEnd(companyId,targetPid,Math.min(targetOrderNum,orderNum),Math.max(targetOrderNum,orderNum),num);
                    if (num == 1) {
                        // 如果目标序号 小于当前序号
                        // 自身 = 目标序号 + 1
                        moveChapter.setOrderNum(targetOrderNum + 1);
                    } else {
                        //  目标序号大于 当前序号
                        // 自身 = 目标序号
                        moveChapter.setOrderNum(targetOrderNum);
                        // 目标 = 目标序号 - 1
                        chapter.setOrderNum(targetOrderNum - 1);
                    }
                }
            }
        }
        if (changeParent) {
            if (!StrUtil.equals(type,"inner")) {
                // 处理pid pids
                String newPids = StrUtil.emptyToDefault(chapter.getPids(),"");
                String oldPids = moveChapter.getPids();
                moveChapter.setPid(chapter.getPid());
                moveChapter.setPids(newPids);
                updateChapterChildrenPids(moveChapter.getId(),companyId,newPids,oldPids);
            }
        }

        moveChapter.setSpecId(chapter.getSpecId());
        updateCusSubcontractChapter(chapter);
        updateCusSubcontractChapter(moveChapter);
    }

    @Override
    public List<String> getOptionalSpecList(Long companyId) {
        return dmcFbChapterMapper.getOptionalSpecList(companyId);
    }

    @Override
    public StaFbChapter getStaFbChapterById(String id, String specId, Long companyId) {
        String newestId = staVersionMapper.getNewestId(companyId, CusConstants.GX_TYPE,specId);
        return staFbChapterMapper.selectStaFbChapterById(newestId,id);
    }


    private int updateCusSubcontractChapter(CusFbChapter chapter) {
        LambdaQueryWrapper<CusFbChapter> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(CusFbChapter::getCompanyId,chapter.getCompanyId());
        queryWrapper.eq(CusFbChapter::getId,chapter.getId());
        int update = dmcFbChapterMapper.update(chapter, queryWrapper);
        return update;
    }

    private void updateChapterChildrenPids(String id, Long companyId, String newPids, String oldPids) {
        List<CusFbChapter> children = dmcFbChapterMapper.selectChildrenById(id,companyId);
        if (CollUtil.isNotEmpty(children)) {
            for (CusFbChapter child : children) {
                child.setPids(child.getPids().replaceFirst(oldPids,newPids));
            }
            dmcFbChapterMapper.updateChildrenPids(children,companyId);
        }
    }

    private String getChildMaxLengthPids(String id,Long companyId) {
        return dmcFbChapterMapper.getChildMaxLengthPids(id,companyId);
    }


    private void orderNumProcessStartEnd(Long companyId, String pid, int startNum, int endNum, int num) {
        if (num == 1 || num == -1) {
            dmcFbChapterMapper.orderNumProcessStartEnd(companyId,pid,startNum,endNum,num);
        } else {
            throw new ServiceException("序号参数错误");
        }
    }

    private void orderNumProcess(Long companyId, String pid, Integer orderNum, int num) {
        if (num == 1 || num == -1) {
            dmcFbChapterMapper.orderNumProcess(companyId,pid,orderNum,num);
        } else {
            throw new ServiceException("序号参数错误");
        }


    }

    private CusFbChapter getById(String id,Long companyId) {
        return dmcFbChapterMapper.selectOne(
                Wrappers.<CusFbChapter>lambdaQuery()
                        .eq(CusFbChapter::getCompanyId, companyId)
                        .eq(CusFbChapter::getId, id)
        );
    }

    private Integer maxOrderNum(String pid,Long companyId) {
        return dmcFbChapterMapper.maxOrderNum(pid,companyId);
    }


}
